﻿using GXDLMSDirector;
using Kn.DLMS;
using Kn.DLMS.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using WindowsFormsApplication3;

namespace Kn.ALICE
{
    #region GXAliceData基类
    public class GXAliceData
    {
        public ushort SID { get; set; }
        public bool IsAck { get; set; }
        public GXByteBuffer Buff = new GXByteBuffer();

        public string Name { get; set; }
        public string strUIData = "";
        public string ReverseString(string input)
        {
            char[] charArray = input.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }
        public string ConvertSerialNumber(byte[] serialNumber)
        {
            // 去掉第一个字节 0x0B
            byte[] trimmedSerialNumber = serialNumber.Skip(1).ToArray();

            // 转换为十六进制字符串
            string hexString = BitConverter.ToString(trimmedSerialNumber).Replace("-", "");

            hexString = ReverseString(hexString);
            // 插入分隔符 "-"
            string formattedSerialNumber = hexString.Insert(3, "-").Insert(6, "-").Insert(9, "-").Insert(24, "-");

            return formattedSerialNumber;
        }

        public  string ConvertHexToAscii(string hexString)
        {
            string[] hexValues = hexString.Split(' ');
            StringBuilder asciiBuilder = new StringBuilder();

            foreach (string hex in hexValues)
            {
                int value = Convert.ToInt32(hex, 16);
                char charValue = (char)value;
                asciiBuilder.Append(charValue);
            }

            return asciiBuilder.ToString();
        }

        public  string GetBroadcastFlagDescription(BroadcastFlag flag)
        {
            switch (flag)
            {
                case BroadcastFlag.Unicast:
                    return "单播";
                case BroadcastFlag.Broadcast:
                    return "广播";
                default:
                    return "未知";
            }
        }
        public  string GetAddressFormatDescription(AddressFormat format)
        {
            switch (format)
            {
                case AddressFormat.BCD:
                    return "BCD格式";
                case AddressFormat.BIN:
                    return "BIN格式";
                case AddressFormat.ASCII:
                    return "ASCII格式";
                default:
                    return "未知";
            }
        }

        public  string GetPacketTypeDescription(PacketType type)
        {
            switch (type)
            {
                case PacketType.Unspecified:
                    return "不限定";
                case PacketType.TextMessage:
                    return "文本短消息";
                case PacketType.PDUMessage:
                    return "PDU短消息";
                default:
                    return "未知";
            }
        }



        public virtual bool Parser()
        {
            // 可以在派生类中重写该方法



            return true;
        }


    }
    #endregion

    #region GXAliceData8110类 接口配置-CU报告必备信息
    public class GXAliceData8110 : GXAliceData
    {
        #region 属性
        public ushort ALICEVersion { get; set; } = 0x0100; // ALICE版本1.00
        public byte[] BaudRateAndParity { get; set; } = { 0x00, 0x00, 0x00, 0x00 }; // 波特速率及校验信息
        public byte MissgingTime { get; set; } = 0x00; // CU可设置失联初始化时间最大能力值：不使用

        public ushort InterfaceRxBufferLength { get; set; } = 0x0206; // 接口接收缓冲长度：518

        public byte CUlinkDirection { get; set; } = 0x00; //CU链路方向：不使用

        public byte AT { get; set; } = 0x00; //AT命令集：不使用
        /*
        CU序列号 = 001-01-01-00000000123456-6
        项目/地区：001 = 印尼智能电表
        厂商：01 = 万高
        资产类型：01 = 载波模块-单模
        产品序列号：00000000123456
        校验码：6
        */

        public byte[] CUSerialNumber { get; set; } = { 0x0B, 0x66, 0x45, 0x23, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00 }; // CU序列号
        public GXCUModuleID CUModuleID = new GXCUModuleID();


        public byte[] MAC { get; set; } = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        public byte IMEILen { get; set; } = 0x00;

        public byte[] IMEINumber { get; set; } = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; //IMEI

        #endregion

        public GXAliceData8110()
        {
            SID = 0x8110;
            Name = "CU模块报告必备信息<0x81,0x10>";
        }

        public string GetReponseType(byte AT)
        {

            string ATresult = "";

            if( (AT & (byte)(0x01))  == 0x01 )
            {
                ATresult += "D0=1, 支持: Q / GDW 10376.3 - 2019";
            }

            if ( (AT & (byte)(0x02)) == 0x02 )
            {
                ATresult += "D1=1, 支持: D1:3GPP TS 27.007";
            }

            return ATresult;

        }



        public static string ConvertIMEINumber(byte[] byteArray)
        {
            StringBuilder sb = new StringBuilder(byteArray.Length);
            foreach (byte b in byteArray)
            {
                sb.Append((char)b);
            }
            return sb.ToString();
        }

        public static string ConvertHexToIMEINumber(string hexString)
        {
            byte[] byteArray = new byte[hexString.Length / 2];
            for (int i = 0; i < hexString.Length; i += 2)
            {
                string hexByte = hexString.Substring(i, 2);
                byteArray[i / 2] = Convert.ToByte(hexByte, 16);
            }

            Array.Reverse(byteArray); // 反转字节数组的顺序

            string intermediateString = ConvertIMEINumber(byteArray);
            string finalString = ConvertIMEINumber(Encoding.ASCII.GetBytes(intermediateString));

            return finalString;
        }


        public override bool Parser()
        {
            try
            {
                ALICEVersion = Buff.GetUInt16();
                Buff.Get(BaudRateAndParity);
                MissgingTime = Buff.GetUInt8();
                InterfaceRxBufferLength = Buff.GetUInt16();
                CUlinkDirection = Buff.GetUInt8();
                AT = Buff.GetUInt8();
                Buff.Get(CUSerialNumber);
                Buff.Get(MAC);
                IMEILen = Buff.GetUInt8();
                if(IMEILen != 0)
                {
                    Buff.Get(IMEINumber);  //HPLC 没有IMEI IMEI 是国际移动设备识别码（International Mobile Equipment Identity）的缩写。它是一个唯一的 15 位数字代码，用于识别个别移动设备，如智能手机或平板电脑。
                }


                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(2) + ": ALICE版本" + ALICEVersion.ToString("X4").Insert(2, ".") + "\r\n";
                strUIData += Buff.GetString(4) + ": 波特速率及校验信息\r\n";
                strUIData += Buff.GetString(1) + ": CU可设置失联初始化时间最大能力值:" + MissgingTime.ToString("X2") + "\r\n";
                strUIData += Buff.GetString(2) + ": 接口接收缓冲长度:" + InterfaceRxBufferLength.ToString() + "\r\n";
                strUIData += Buff.GetString(1) + ": CU链路方向:" + CUlinkDirection.ToString() + "\r\n";
                strUIData += Buff.GetString(1) + ": AT命令集:" + AT.ToString()+ "(" + GetReponseType(AT) + ")"+ "\r\n";

                strUIData += Buff.GetString(1) + ": CU序列号长度:" + CUSerialNumber[0].ToString() + "\r\n";

                CUModuleID.strCuId = ConvertSerialNumber(CUSerialNumber);
                strUIData += Buff.GetString(CUSerialNumber.Length-1) + ": CU序列号:" + ConvertSerialNumber(CUSerialNumber) + "\r\n";
                strUIData += CUModuleID.strUi;
                strUIData += Buff.GetString(6) + ": MAC地址" + "\r\n";  //未入网填入全0 已入网填入组网MAC地址4G全0

                strUIData += Buff.GetString(1) + ": IMEI长度" + IMEILen.ToString() + "\r\n";//HPLC不使用，固定为0 4G按照实际
                if (IMEILen != 0)
                {

                    string hexString = BitConverter.ToString(IMEINumber).Replace("-", "");
                    string imeiNumberString = ConvertHexToIMEINumber(hexString);
                    strUIData += Buff.GetString(IMEILen) +": IMEI移动设备号: " + imeiNumberString +  "\r\n";
                }
       

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region GXAliceData0120类 接口配置-DE发送必备信息
    public class GXAliceData0120 : GXAliceData
    {
        #region 属性
        // ALICE版本
        public ushort ALICEVersion { get; set; } = 0x0100; // ALICE版本1.00

        // DE类型
        private byte _DEType;
        public byte DEType
        
        {
            get
            {
                return _DEType;
            }
            set
            {
                
                if (value == 1)
                {
                    strDEType = "1:电气";
                }
                else if (value == 2)
                {
                    strDEType = "2:非电气";
                }
                else 
                {
                    strDEType = value.ToString() + ":未知类型";
                }

                _DEType = value;
            }
        }

        public string strDEType = "";
        // 接口交互最大报文长度
        public ushort MaxMessageLength { get; set; }

        // 上次会话通信波特率
        public byte[] LastSessionBaudRate { get; set; } = { 0, 0, 0, 0 };

        // 当前时间
        public byte[] CurrentTime { get; set; }

        public string MeterCurrentTime { get; set; }
        // 序列号长度
        public byte SerialNumberLength { get; set; }
        public string strSerialNumberForma { get; set; }
        // 序列号格式
        private byte _SerialNumberFormat;
        public byte SerialNumberFormat
        {
            get
            {
                return _SerialNumberFormat;
            }
            set
            {
                if (value == 1)
                {
                    strSerialNumberForma = "1:BCD";
                }
                else if (value == 2)
                {
                    strSerialNumberForma = "2:BIN";
                }
                else if (value == 3)
                {
                    strSerialNumberForma = "3:ASCII";
                }
                else
                {
                    strSerialNumberForma = value.ToString() + ":未知格式";
                }
                _SerialNumberFormat = value;
            }
        }
        // 序列号
        public byte[] SerialNumber { get; set; }
        private string _strSerialNumber;
        public string strSerialNumber 
        { 
            get
            {
                return (_strSerialNumber);
            }
            set
            {
                _strSerialNumber = value;
                meterAddress = value.Substring(0, 12);
                materialSerialNumber = value.Substring(12, 40-12);

          
            }
        }

        public string meterAddress { get; set; }
        public string materialSerialNumber { get; set; }

        #endregion

        public GXAliceData0120()
        {
            SID = 0x0120;
            Name = "电表DE发送必备信息<0x01,0x20>";
        }


        public override bool Parser()
        {
            try
            {
                ALICEVersion = Buff.GetUInt16();  //ALICE版本协议版本
                DEType = Buff.GetUInt8();         //DE 类型

                MaxMessageLength = Buff.GetUInt16();  
                Buff.Get(LastSessionBaudRate);
                MeterCurrentTime = Buff.GetString(6); //电表当前时间


                string[] hexArray = MeterCurrentTime.Split(' ');
                string year =  "20" + hexArray[5];  // 年份
                string month = hexArray[4];        // 月份
                string day = hexArray[3];          // 日
                string hour = hexArray[2];         // 小时
                string minute = hexArray[1];       // 分钟
                string second = hexArray[0];       // 秒

                MeterCurrentTime = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;


                SerialNumberLength = Buff.GetUInt8();
                SerialNumberFormat = Buff.GetUInt8();
                strSerialNumber = ConvertHexToAscii(Buff.GetString(40));
                strSerialNumber = ReverseString(strSerialNumber);

                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(2) + ": ALICE版本" + ALICEVersion.ToString("X4").Insert(2, ".") + "\r\n";
                strUIData += Buff.GetString(1) + ": DE类型:" + strDEType + "\r\n";
                strUIData += Buff.GetString(2) + ": 接口交互最大报文长度：" + MaxMessageLength.ToString()+"\r\n";
                strUIData += Buff.GetString(4) + ": 上次会话通信波特率:不使用" + "\r\n";
                strUIData += Buff.GetString(6) + ": 电表当前时间:" + MeterCurrentTime + "\r\n";
                strUIData += Buff.GetString(1) + ": 序列号长度：" + SerialNumberLength.ToString() + "字节（表地址+物料号）\r\n";
                strUIData += Buff.GetString(1) + ": 序列号格式：" + strSerialNumberForma + "\r\n";

                strUIData += Buff.GetString(40) + ": 印尼电表表地址: " + meterAddress + " 物料序列号:"+ materialSerialNumber +"\r\n";


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }
    #endregion

    #region GXAliceData0202类 信道特征信息
    public class GXAliceData0202 : GXAliceData
    {
        #region 属性
        ChannelFeatureDirectory featureDirectory = new ChannelFeatureDirectory();
        List<GXAliceChannelFeature> channelFeatures = new List<GXAliceChannelFeature>();
        #endregion

        public GXAliceData0202()
        {
            SID = 0x0202;
            Name = "请求CU通信模块信道特征信息<0x02,0x02>";
        }

        public override bool Parser()
        {
            try
            {
                while(Buff.Position != Buff.Size)
                {
                    ushort Code = Buff.GetUInt16();
                    if (featureDirectory.FeatureDictionary.ContainsKey(Code))
                    {
                        // 如果 short code 存在于字典中，将对应的特征添加到 channelFeatures 列表中
                        channelFeatures.Add(featureDirectory.FeatureDictionary[Code]);
                    }
                    else
                    {
                        GXAliceChannelFeature UnKnowFeature = new GXAliceChannelFeature();
                        UnKnowFeature.Code = Code;
                        UnKnowFeature.Name = "控制命令参数编码:未知";
                        channelFeatures.Add(UnKnowFeature);
                    }
                }


                Buff.Position = 0;
                strUIData = "";

                foreach (var feature in channelFeatures)
                {
                    strUIData += Buff.GetString(2) + ": 控制命令参数编码：" + feature.Name + "\r\n";
                }
                   

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }
    #endregion

    #region GXAliceData8202类 模块回复信道特征信息
    public class GXAliceData8202 : GXAliceData
    {
        #region 属性
        ChannelFeatureDirectory featureDirectory = new ChannelFeatureDirectory();
        GXAliceChannelFeature feature = new GXAliceChannelFeature();
        #endregion

        public GXAliceData8202()
        {
            SID = 0x8202;
            Name = "模块回复信道特征信息<0x82,0x02>";
        }

        
        public override bool Parser()
        {
            try
            {

                ushort Code;
                int Len;

                GXByteBuffer UIbuf = new GXByteBuffer();
                for (int i = 0; i < Buff.Size; i++)
                {
                    UIbuf.SetUInt8(Buff.GetUInt8());
                }

                Buff.Position = 0;
                
                while(Buff.Position != Buff.Size)
                {
                    Code = Buff.GetUInt16();
                    Len = Buff.GetUInt16();

                    feature = featureDirectory.FeatureDictionary[Code];
                    feature.dataBuf.Clear();

                    Buff.Position -= 4;

                    for (int j = 0; j < 4 + Len; j++)
                    {
                        feature.dataBuf.SetUInt8(Buff.GetUInt8());
                    }


                    feature.Parser();
                    strUIData += feature.strUIParseResult;
                }

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
        
    }
    #endregion

    #region GXAliceData0303类 电表给模块发软复位命令
    public class GXAliceData0303 : GXAliceData
    {
        #region 属性
        public byte CuInitCmd { get; set; }           //初始化命令
        public byte ResponseDelay { get; set; } //响应延时
        public ushort ControlCode { get; set; } //控制命令编码

        public ushort DataLen { get; set; }    //数据长度
        #endregion

        #region 方法
        public string ParseCuInitCmd(byte CuInitCmd)
        {
            string result = "";

            if ((CuInitCmd & 0x01) == 0x01)
            {
                result += "D0=1，参数初始化\n";
            }
            if ((CuInitCmd & 0x02) == 0x02)
            {
                result += "D1=2，硬件初始化\n";
            }
            if ((CuInitCmd & 0x04) == 0x04)
            {
                result += "D2=3，数据初始化\n";
            }
            if ((CuInitCmd & 0x08) == 0x08)
            {
                result += "D3=4，模块软复位(响应电表命令后，再执行复位)\n";
            }

            if (result.Length > 0 && result.EndsWith("\n"))
            {
                result = result.Substring(0, result.Length - 1);
            }

            return result;
        }

        #endregion

        public GXAliceData0303()
        {
            SID = 0x0303;
            Name = "电表给模块发软复位命令<0x03,0x03>";
        }

        public override bool Parser()
        {
            try
            {
        
       
                ControlCode = Buff.GetUInt16();
                DataLen = Buff.GetUInt16();
                CuInitCmd = Buff.GetUInt8();
                ResponseDelay =  Buff.GetUInt8();

                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(2) + ": 控制命令参数编码："  + ControlCode.ToString("0000") + "\r\n";
                strUIData += Buff.GetString(2) + ": 数据长度=" + DataLen.ToString() + "\r\n";
                strUIData += Buff.GetString(1) + ": " + ParseCuInitCmd(CuInitCmd) + "\r\n";
                strUIData += Buff.GetString(1) + ": 响应延时:" + ResponseDelay.ToString() + "s\r\n";


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }


    }
    #endregion

    #region GXAliceData0304类 信道配置-DE/CU用户数据发送命令
    public class GXAliceData0304 : GXAliceData
    {
        #region 属性
        public BroadcastFlag broadcastFlag { get; set; }
        public ushort packetNumber { get; set; }
        public PacketType packetType { get; set; }
        public byte charsetNumber { get; set; }
        public AddressFormat destinationAddressFormat { get; set; }
        public byte[] destinationAddress { get; set; }
        public ushort contentLength { get; set; }
        public byte destinationAddressLength;
        public GXByteBuffer content = new GXByteBuffer();

        public byte SPLNPro;

        public NetworkEndpoint Remote = new NetworkEndpoint();

        private DLMSTranslator dlmsTranslator = new DLMSTranslator();
        #endregion

        public GXAliceData0304()
        {
            SID = 0x0304;
            Name = "DE/CU用户数据发送命令<0x03,0x04>";
        }

        public override bool Parser()
        {
            try
            {

                broadcastFlag = (BroadcastFlag)Buff.GetUInt8();
                packetNumber = Buff.GetUInt16();
                packetType = (PacketType)Buff.GetUInt8();
                charsetNumber = Buff.GetUInt8();
                destinationAddressFormat = (AddressFormat)Buff.GetUInt8();
                destinationAddressLength = Buff.GetUInt8();
                destinationAddress = new byte[destinationAddressLength];
                Buff.Get(destinationAddress);
                contentLength = Buff.GetUInt16();
                SPLNPro = Buff.GetUInt8();
                content.Clear();
                content.SetUInt8(SPLNPro);
                for (int i = 0; i < contentLength-1; i++)
                {
                    content.SetUInt8(Buff.GetUInt8());
                }

                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(1) + ": 广播标识：" + GetBroadcastFlagDescription(broadcastFlag) + "\r\n";
                strUIData += Buff.GetString(2) + ": 数据包序号：不使用" + "\r\n";
                strUIData += Buff.GetString(1) + ": 数据包类型：" + GetPacketTypeDescription(packetType) + "\r\n";
                strUIData += Buff.GetString(1) + ": 字符集编号：不使用" + "\r\n";
                strUIData += Buff.GetString(1) + ": 对端地址格式：" + GetAddressFormatDescription(destinationAddressFormat )+ "\r\n";
                strUIData += Buff.GetString(1) + ": 对端地址长度：" + destinationAddressLength.ToString()+ "字节\r\n";
                if(destinationAddressLength==0)
                {
                    //strUIData += Buff.GetString(destinationAddressLength) + ":对端地址：" + "\r\n";
                }
                else
                {
                    if(destinationAddressFormat == AddressFormat.BIN) //2=BIN
                    {
                        Remote.ByteIpAddress[0] = destinationAddress[0];
                        Remote.ByteIpAddress[1] = destinationAddress[1];
                        Remote.ByteIpAddress[2] = destinationAddress[2];
                        Remote.ByteIpAddress[3] = destinationAddress[3];

                        Remote.BytePort[0] = destinationAddress[4];
                        Remote.BytePort[1] = destinationAddress[5];
                        Remote.Parser();
                        strUIData += Buff.GetString(4) + ":上报IP：" + Remote.IpAddress + "\r\n";
                        strUIData += Buff.GetString(2) + ":上报端口：" + Remote.Port.ToString() +  "\r\n";
                    }
                    else
                    {
                        strUIData += Buff.GetString(destinationAddressLength) + ":对端地址：" + "\r\n";
                    }
                    
                }
                string strSPLNPro = "未知协议";
                if (SPLNPro == 0x7E) strSPLNPro = "HDLC协议";
                if (SPLNPro == 0x00) strSPLNPro = "Wrapper协议";
                strUIData += Buff.GetString(2) + ": 内容长度：" + contentLength.ToString() + "字节 内容如下: " + strSPLNPro + "\r\n";

                string strConnet = Buff.GetString(contentLength);
                strUIData += strConnet + "" + "\r\n";
                strUIData += dlmsTranslator.DlmsTranslator(strConnet);

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }


    }
    #endregion

    #region GXAliceData0301类 信道配置-DE发送信道配置参数
    public class GXAliceData0301 : GXAliceData
    {
        public byte LabelCount { get; set; }
        public byte LabelInfo { get; set; }

        public GXAlicChannelConfigDictionary Dic = new GXAlicChannelConfigDictionary();

        public GXAliceChannelConfig Para = new GXAliceChannelConfig();
        public GXAliceData0301()
        {
            SID = 0x0301;
            Name = "DE发送信道配置参数<0x03,0x01>";
        }

        public override bool Parser()
        {
            try
            {

                ushort Code;
                int Len;

                GXByteBuffer UIbuf = new GXByteBuffer();

                for(int i = 0; i < Buff.Size; i++)
                {
                    UIbuf.SetUInt8(Buff.GetUInt8());
                }

                Buff.Position = 0;
                LabelCount = Buff.GetUInt8();
                LabelInfo = Buff.GetUInt8();
                strUIData += UIbuf.GetString(1) + ": 配置数据组的标签总个数 " + LabelCount.ToString() + "\r\n";
                strUIData += UIbuf.GetString(1) + ": 配置数据组的标签信息 "   + LabelInfo.ToString() + "\r\n";


                for (int i = 0; i < LabelCount; i++)
                {
                    Code = Buff.GetUInt16();
                    Len  = Buff.GetUInt16();

                    Para = Dic.ChannelConfigDictionary[Code];
                    Para.ParaBuf.Clear();

                    Buff.Position -= 4;
 
                    for (int j = 0; j < 4+ Len; j++)
                    {
                        Para.ParaBuf.SetUInt8(Buff.GetUInt8());
                    }
              

                    Para.Parser();
                    strUIData += Para.strUIParseResult;
                }

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }



    }
    #endregion DE发送信道配置参数 DE发送信道配置参数

    #region GXAliceData0310类 信道配置-DE查询信道配置参数
    public class GXAliceData0310 : GXAliceData
    {
        public GXAlicChannelConfigDictionary Dic = new GXAlicChannelConfigDictionary();
        public GXAliceChannelConfig Para = new GXAliceChannelConfig();
        public GXAliceData0310()
        {
            SID = 0x0310;
            Name = "电表DE查询模块的信道配置参数<0x03,0x10>";
        }

        public override bool Parser()
        {
            try
            {
                ushort Code;
                int Len;
                GXByteBuffer UIbuf = new GXByteBuffer();
                for (int i = 0; i < Buff.Size; i++)
                {
                    UIbuf.SetUInt8(Buff.GetUInt8());
                }

                Buff.Position = 0;

                while(Buff.Position != Buff.Size)
                {
                    Code = Buff.GetUInt16();
                    Len = Buff.GetUInt16();

                    Para = Dic.ChannelConfigDictionary[Code];
                    Para.ParaBuf.Clear();

                    Buff.Position -= 4;

                    for (int j = 0; j < 4 + Len; j++)
                    {
                        Para.ParaBuf.SetUInt8(Buff.GetUInt8());
                    }


                    Para.Parser();
                    strUIData += Para.strUIParseResult;
                }

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region GXAliceData8401类 状态更新-CU向DE更新信道状态信息
    public class GXAliceData8401 : GXAliceData
    {
        public ushort code;
        public ushort len;
        public GXAliceCLD_DICTIONARY CLDDic = new GXAliceCLD_DICTIONARY();

        GXAliceCLD Cld;
        public GXAliceData8401()
        {
            SID = 0x8401;
            Name = "CU向DE更新信道状态信息<0x84,0x01>";
        }

       
        public override bool Parser()
        {
            try
            {
                code = Buff.GetUInt16();
                len = Buff.GetUInt16();
                if (CLDDic.AliceCLDDictionary.Keys.Contains(code))
                {
                    Cld = CLDDic.AliceCLDDictionary[code];
                }
                else
                {
                    Cld = CLDDic.AliceCLDDictionary[0xFFFF];
                }

                Cld.dataBuf.Set(Buff);
                Cld.Parser();


                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(2) + " :编码:" + code.ToString("X4") + "\r\n";
                strUIData += Buff.GetString(2) + " :数据长度:" + len.ToString() + "字节\r\n";
                strUIData += Cld.strData;
 

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion 

    #region GXAliceData0401类 状态更新-DE查询CU信道状态信息
    public class GXAliceData0401 : GXAliceData
    {
        public GXAliceData0401()
        {
            SID = 0x0401;
            Name = "DE查询CU信道状态信息<0x04,0x01>";
        }

    }
    #endregion

    #region GXAliceData0310类 电表请求模块的非技术信息<0x05,0x02>
    public class GXAliceData0502 : GXAliceData
    {
        public GXAliceData0502()
        {
            SID = 0x0502;
            Name = "电表查询模块版本信息0x05,0x02>";
        }

    }
    #endregion

    #region GXAliceData8502类 模块回复非技术信息<0x85,0x02>
    public class GXAliceData8502 : GXAliceData
    {
        #region 属性
        public GXCUModuleID cuid = new GXCUModuleID();
        public IMEI immi = new IMEI();
        public GXModuleModel model = new GXModuleModel();
        public Byte[] MAC = new byte[6];

        public GXManufacturerIdentifier manufacturerIdentifier = new GXManufacturerIdentifier();
        public GXModuleSoftVersion softVersion = new GXModuleSoftVersion();

        public Byte[] ProductCertificationRegistrationNumber = new byte[8];
        public Byte[] ProductCertificationInformationFieldLen = new byte[2];

        public GXModuleSolution moduleSolution = new GXModuleSolution();
        #endregion

        public GXAliceData8502()
        {
            SID = 0x8502;
            Name = "模块回复非技术信息<0x85,0x02>";
        }



        public override bool Parser()
        {
            try
            {
                cuid.CUSerialNumberLen = Buff.GetUInt8();
                Buff.Get(cuid.CUSerialNumber);
                cuid.Parser();

                Buff.Get(MAC);

                immi.IMEILen = Buff.GetUInt8();
                if(immi.IMEILen != 0)
                {
                    Buff.Get(immi.IMEINumber);
                    immi.Parser();
                }

                model.TypeLen = Buff.GetUInt8();
                Buff.Get(model.TypeValue);
                model.Parser();


                Buff.Get(manufacturerIdentifier.Value);
                manufacturerIdentifier.Parser();

                softVersion.Len = Buff.GetUInt8();
                Buff.Get(softVersion.Value);
                softVersion.Parser();

                Buff.Get(ProductCertificationRegistrationNumber);
                Buff.Get(ProductCertificationInformationFieldLen);

                Buff.Get(moduleSolution.Value);
                moduleSolution.Parser();

                Buff.Position = 0;
                strUIData = "";
                strUIData += Buff.GetString(1) + ":CU序列号长度" + cuid.CUSerialNumberLen.ToString() +  "\r\n";
                strUIData += Buff.GetString(cuid.CUSerialNumberLen) + cuid.strUi;  //":CU序列号\r\n";

                strUIData += Buff.GetString(6)   + ":MAC地址\r\n";


                strUIData += Buff.GetString(1)   + ":IMEI长度" + immi.IMEILen.ToString() + "\r\n";
                if(immi.IMEILen != 0)
                {
                    strUIData += Buff.GetString(immi.IMEILen)  + " :国际移动设备身份码IMEI " + immi.strUIResult +  "\r\n";
                }
                strUIData += Buff.GetString(1)   + " :型号长度" + model.TypeLen.ToString() + "\r\n";
                strUIData += Buff.GetString(model.TypeLen)   + " :型号 " + model.strUIResult  + "\r\n";

                strUIData += Buff.GetString(8)   + " :厂家标识" +  manufacturerIdentifier.strUIResult  + "\r\n";

                strUIData += Buff.GetString(1)   + " :产品版本长度" + softVersion.Len.ToString() + "\r\n";

                strUIData += Buff.GetString(softVersion.Len)  + " :软件版本号 " + softVersion.strValue + "\r\n";

                strUIData += Buff.GetString(8)   + ":产品认证注册号 固定填入0 不使用\r\n";

                strUIData += Buff.GetString(2)   + " :CU产品认证信息域长度 固定填入0 不使用\r\n";
                
                strUIData += Buff.GetString(32)  + " :解决方案 模组版本号 " + moduleSolution.strValue + "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region GXAliceDataReply类 通用响应报文
    public enum ResponseType
    {
        Success = 0,
        AcceptNoData = 1,
        RejectWithSuggestion = 2,
        RejectWithReason = 3
    }

    public enum ReasonCode
    {
        SIDNotRecognized = 0x01,
        DataFormatError = 0x02,
        Busy = 0x03,
        BufferSpaceInsufficient = 0x04,
        MaxLengthExceeded = 0x05,
        UnknownError = 0xFF
    }

    public class GXAliceDataReply : GXAliceData
    {
        public ResponseType Result { get; set; }   //响应

        public GXByteBuffer Data { get; set; }     //数据内容

        public ReasonCode ErrorCode { get; set; }      //错误原因

        public byte[] RemainLen { get; set; } = { 0x00, 0x00 };   //剩余缓冲区长度
        public ushort dataLength { get; set; } //数据内容长度
        public byte[] dataContent { get; set; } = { 0x00, 0x00 };  //数据内容长度

        public string errorInfo { get; set; }

        public GXAliceDataReply()
        {
            SID = 0xFFFF;
            Name = "响应确认帧";
        }


        public string GetReponseType(ResponseType type)
        {
            if (type == ResponseType.Success)          return ("0-成功");
            if (type == ResponseType.AcceptNoData)     return ("1-接受,无法提供数据");
            if (type == ResponseType.AcceptNoData)     return ("2-拒绝,返回建议值");
            if (type == ResponseType.RejectWithReason) return ("3-拒绝,返回原因码和原因内容");
            return ("" + type.ToString() + "--未知");
        }

        public string GetReasonCode(ReasonCode code)
        {
            byte tmp = (byte)code;
            string strCode = "0x" + tmp.ToString("X2");
            if (code == ReasonCode.SIDNotRecognized) return (strCode + "--SID不识别:");
            if (code == ReasonCode.DataFormatError) return (strCode + "--DATA数据格式错");
            if (code == ReasonCode.Busy) return (strCode + ": 忙");
            if (code == ReasonCode.BufferSpaceInsufficient) return (strCode + "--数据缓冲区空间不足,数据缓冲区剩余长度如下:");
            if (code == ReasonCode.MaxLengthExceeded) return (strCode + "--超出最大允许长度,建议值如下:");
            if (code == ReasonCode.UnknownError) return (strCode + "--未知错误");
            return ("" + strCode + "--未知");
        }

        public override bool Parser()
        {

            try
            {
                errorInfo = " :原因内容";
                Result = (ResponseType)Buff.GetUInt8();

                if (Result == ResponseType.RejectWithReason)
                {
                    Buff.Get(RemainLen);
                    dataLength = Buff.GetUInt16();
                    ErrorCode = (ReasonCode)Buff.GetUInt8();

                    if(ErrorCode == ReasonCode.Busy)
                    {
                        ushort info = Buff.GetUInt16();
                        errorInfo = " :预计等待时间" + info.ToString() + "ms";
                    }

                    if (ErrorCode == ReasonCode.BufferSpaceInsufficient)
                    {
                        ushort info = Buff.GetUInt16();
                        errorInfo = " :数据缓冲区剩余长度" + info.ToString() + "字节";
                    }

                    if (ErrorCode == ReasonCode.MaxLengthExceeded)
                    {
                        ushort info = Buff.GetUInt16();
                        errorInfo = " :建议值" + info.ToString() + "字节";
                    }
                }


                Buff.Position = 0;

                strUIData = "";
                strUIData += Buff.GetString(1) + " :响应类型" + GetReponseType(Result) + "\r\n";
                strUIData += Buff.GetString(2) + " :剩余缓冲区长度\r\n";
                strUIData += Buff.GetString(2) + " :数据内容长度:" + dataLength.ToString() + "字节\r\n";

                if (Result == ResponseType.RejectWithReason)
                {
                    strUIData += Buff.GetString(1) + " :原因码:" + GetReasonCode(ErrorCode) + "\r\n";

                    if(dataLength - 1 > 0)
                    {
                        strUIData += Buff.GetString(dataLength - 1) + errorInfo +  "\r\n";
                    }
                }
               
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    public class GXAliceData_DICTIONARY
    {
        #region 原有方式
        //字段
        public Dictionary<ushort, GXAliceData> AliceDataDictionary = new Dictionary<ushort, GXAliceData>(30);

        public GXAliceData_DICTIONARY()
        {
            GXAliceData Data8110 = new GXAliceData8110();
            GXAliceData Data0120 = new GXAliceData0120();
            GXAliceData Data0202 = new GXAliceData0202();
            GXAliceData Data0310 = new GXAliceData0310();
            GXAliceData Data8202 = new GXAliceData8202();
            GXAliceData Data0303 = new GXAliceData0303();
            GXAliceData Data0304 = new GXAliceData0304();
            GXAliceData Data0301 = new GXAliceData0301();
            GXAliceData Data8401 = new GXAliceData8401();
            GXAliceData Data0401 = new GXAliceData0401();
            GXAliceData Data0502 = new GXAliceData0502();
            GXAliceData Data8502 = new GXAliceData8502();

            GXAliceData DataReply = new GXAliceDataReply();

            AliceDataDictionary.Add(Data8110.SID, Data8110);
            AliceDataDictionary.Add(Data0120.SID, Data0120);
            AliceDataDictionary.Add(Data0202.SID, Data0202);
            AliceDataDictionary.Add(Data8202.SID, Data8202);
            AliceDataDictionary.Add(Data0303.SID, Data0303);
            AliceDataDictionary.Add(Data0304.SID, Data0304);
            AliceDataDictionary.Add(Data0301.SID, Data0301);
            AliceDataDictionary.Add(Data0310.SID, Data0310);

            AliceDataDictionary.Add(Data8401.SID, Data8401);
            AliceDataDictionary.Add(Data0401.SID, Data0401);
            AliceDataDictionary.Add(Data0502.SID, Data0502);
            AliceDataDictionary.Add(Data8502.SID, Data8502);

            AliceDataDictionary.Add(DataReply.SID, DataReply);
        }
    }
}
#endregion